package com.zdp.middleware.hystrix;

import com.zdp.middleware.hystrix.annotation.DoHystrix;
import com.zdp.middleware.hystrix.value.IValveService;
import com.zdp.middleware.hystrix.value.impl.HystrixValueImpl;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 熔断注解的切面类
 * @author ZhengDp
 * @Date 2023/5/27 11:55
 */
@Aspect
@Component
public class DoHystrixPoint {

    @Pointcut("@annotation(com.zdp.middleware.hystrix.annotation.DoHystrix)")
    public void aopPoint(){}

    /*
    * 通过方法入参的方式直接拿到注解
    * @annotation(doGovern) ==> 将注解设置到 doGovern参数中
    * 类似于 使用 HystrixCommand 来代理了
    * */
    @Around("aopPoint() && @annotation(doGovern)")
    public Object doRouter(ProceedingJoinPoint jp, DoHystrix doGovern) throws Throwable {
        IValveService valveService = new HystrixValueImpl();
        return valveService.access(jp,getMethod(jp),doGovern,jp.getArgs());
    }

    private Method getMethod(ProceedingJoinPoint jp) throws NoSuchMethodException {
        Signature signature = jp.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        return jp.getTarget().getClass().getMethod(methodSignature.getName(),methodSignature.getParameterTypes());
    }



}
